-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor readers to use type parameters and not concrete vtables #207
refactor readers to use type parameters and not concrete vtables #207
Conversation
src/unstable/read.rs
Outdated
let mut data = ZipFileData::from_local_block(block, reader)?; | ||
|
||
match parse_extra_field(&mut data) { | ||
/* FIXME: check for the right error type here instead of accepting any old i/o |
Check notice
Code scanning / devskim
A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note
src/unstable/read.rs
Outdated
// We can't use the typical ::parse() method, as we follow separate code paths depending | ||
// on the "magic" value (since the magic value will be from the central directory header | ||
// if we've finished iterating over all the actual files). | ||
/* TODO: smallvec? */ |
Check notice
Code scanning / devskim
A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note
src/unstable/read.rs
Outdated
} | ||
if let Some(info) = data.aes_mode { | ||
#[cfg(not(feature = "aes-crypto"))] | ||
/* TODO: make this into its own EntryReadError error type! */ |
Check notice
Code scanning / devskim
A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note
if self.check == res { | ||
Ok(()) | ||
} else { | ||
/* TODO: make this into our own Crc32Error error type! */ |
Check notice
Code scanning / devskim
A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note
26cf755
to
134b355
Compare
- also use git dep for zstd to pull in removal of R: BufRead bound - move new methods into unstable/read.rs - support getting aes verification info from a raw ZipEntry - flesh out other methods from ZipFile -> ZipEntry - now create a streaming abstraction - move some methods around
134b355
to
020a61a
Compare
2574c06
to
f0faf24
Compare
src/crc32.rs
Outdated
return self | ||
.check_matches() | ||
.map(|()| 0) | ||
/* TODO: use io::Error::other for MSRV >=1.74 */ |
Check notice
Code scanning / devskim
A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note
src/crc32.rs
Outdated
if self.check == res { | ||
Ok(()) | ||
} else { | ||
/* TODO: make this into our own Crc32Error error type! */ |
Check notice
Code scanning / devskim
A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note
7223f67
to
872bd35
Compare
src/crc32.rs
Outdated
if self.check == res { | ||
Ok(()) | ||
} else { | ||
/* TODO: make this into our own Crc32Error error type! */ |
Check notice
Code scanning / devskim
A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note
src/crc32.rs
Outdated
if self.check == res { | ||
Ok(()) | ||
} else { | ||
/* TODO: make this into our own Crc32Error error type! */ |
Check notice
Code scanning / devskim
A "TODO" or similar was left in source code, possibly indicating incomplete functionality Note
This reverts commit fd11f28.
315623d
to
bbee45b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a partial review.
@@ -0,0 +1,751 @@ | |||
//! Alternate implementation of [`crate::read`]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Document when to use this and when to use the main impl. Also, please remove everything we're not using internally -- we don't need a second public API.
use crate::unstable::read::{ | ||
construct_decompressing_reader, find_entry_content_range, CryptoEntryReader, CryptoVariant, | ||
}; | ||
pub use crate::unstable::read::{ArchiveEntry, ZipEntry}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't need to be public.
pub use crate::unstable::read::{ArchiveEntry, ZipEntry}; | |
pub(crate) use crate::unstable::read::{ArchiveEntry, ZipEntry}; |
https://github.com/zip-rs/zip2/tree/wrapped-reader-refactor is a squashed and rebased version of this PR, but it doesn't build (mainly due to type mismatches involving |
Update: the branch now passes unit tests, and fuzz tests are running on it; but the new code specialized for seekable files is currently unused. @cosmicexplorer Is this a good place for you to resume work from? |
You rock!!! I have just rebased, will address your comments now. |
So @Pr0methean I'd like to raise a small discussion here: the reason I initially made this a draft PR is because I believe there are several shortcomings that necessitate a slight reimplementation, some requiring breaking API changes:
let final_reader = if data.encrypted {
let crypto_variant = CryptoKeyValidationSource::from_data(data)?;
let is_ae2_encrypted = crypto_variant.is_ae2_encrypted();
let crypto_reader = crypto_variant.make_crypto_reader(password, content)?;
let entry_reader =
construct_decompressing_reader(&data.compression_method, crypto_reader)?;
if is_ae2_encrypted {
/* Ae2 voids crc checking: https://www.winzip.com/en/support/aes-encryption/ */
CryptoEntryReader::Ae2Encrypted(entry_reader)
} else {
CryptoEntryReader::NonAe2Encrypted(NewCrc32Reader::new(entry_reader, data.crc32))
}
} else {
/* Not encrypted, so do the same as in .by_index_generic(): */
let entry_reader = construct_decompressing_reader(&data.compression_method, content)?;
CryptoEntryReader::Unencrypted(NewCrc32Reader::new(entry_reader, data.crc32))
}; So that's my case for the API changes. We can do them in pieces, but I'm proposing this intentionally breaking change that I believe will improve the internal architecture and correctness, increase our ability to perform optimizations, and generate more flexible entry structs in our public API. |
I'm experiencing an incredibly strange issue on all web browsers where pushing to this branch isn't being propagated to this PR, and comparing https://github.com/zip-rs/zip2/compare/master...cosmicexplorer:zip:wrapped-reader-refactor?expand=1 acts like they're the same branch. I'm going to close this and create a new PR with the above proposal and see if that fixes this weird issue. |
Moved to #233 which fixes the weird github error in this PR. |
Problem
As described in gyscos/zstd-rs#288 (comment), our usage of
&'a mut dyn Read
inZipFileReader
stops us from being able to implSend
orSync
, or generally to send aZipFile
into a separate thread than the one owning theZipArchive
it belongs to. While this is generally not an issue, as the single synchronousRead + Seek
handle makes it difficult to farm out work to subthreads, for the purposes of #72, we would like to be able to reuse some code instead of creating an entirely separate implementation.That brings us to the second set of issues, surrounding zipcrypto support:
CryptoReader
enum and themake_crypto_reader()
method, even though zip crypto is a very uncommon use case,ZipFile
itself contains some very complex mutable state with both aZipFileReader
and aCryptoReader
, even thoughZipFileReader
itself also contains aCryptoReader
,Crc32Reader
has to maintain a special flag to disable CRC checking in the special case of AE2 encryption, which is a sign of a leaky abstraction and may easily introduce a failure to check CRC in other cases by accident in the future.Solution
Luckily, all of this becomes significantly easier without too many changes:
src/unstable/read.rs
to reimplementread::ZipFile
with the newunstable::read::ZipEntry
.EntryReader
andZipEntry
with a parameterized reader typeR
instead of an internal&'a mut dyn Read
.ZipArchive::by_index()
returningZipResult<ZipEntry<'_, impl Read + '_>>
to avoid leaking internal structs while retaining the ability to rearrange the layout of our internal structs.CryptoReader
creation throughCryptoVariant
.This also leads to a significantly improved refactoring of streaming support in the
streaming
submodule ofsrc/unstable/read.rs
.Result
zipcrypto support doesn't muck up the non-crypto methods,
ZipEntry
is nowSend
, andsrc/unstable/read.rs
is significantly easier to read with equivalent functionality. This will have to be a breaking change in order to achieveSend
-ability, but I believe the readability/maintainability is substantially improved with this change.